
package VISIE;

import Basketball.Ball;
import Basketball.GameManager;
import Basketball.GameStateManagement;
import VISIE.AgentLogic.MainLogicThread;
import VISIE.Games.Dribbling;
import VISIE.Games.Game;
import VISIE.Games.ImitationGame;
import VISIE.Games.Passing;
import VISIE.Games.PickupGame;
import VISIE.Games.Shooting;
import VISIE.navigation.UserNavigation;
import VISIE.recording.Log;
import VISIE.mathfunctions.Conversions;
import VISIE.scenemanager.*;
import VISIE.models.ModelLoader;
import VISIE.network.*;
import VISIE.characters.Character;
import VISIE.characters.*;
import com.jme3.animation.LoopMode;
import com.jme3.app.SettingsDialog;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.control.CharacterControl;
import java.util.List;
import com.jme3.scene.Geometry;
import com.jme3.material.Material;
import com.jme3.system.AppSettings;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.lwjgl.opengl.Display;
import com.jme3.renderer.ViewPort;
import javax.print.attribute.standard.Severity;
import java.util.ArrayList;
import java.net.InetAddress;
import com.jme3.scene.shape.Sphere;
import com.jme3.math.Ray;
import com.jme3.collision.CollisionResults;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.font.Rectangle;
import com.jme3.scene.shape.Box;
import java.io.BufferedReader;
import java.io.FileReader;
import com.jme3.niftygui.NiftyJmeDisplay;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.screen.Screen;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * Example 9 - How to make walls and floors solid.
 * This version uses Physics and a custom Action Listener.
 * @author normen, with edits by Zathras
 */
public class Main extends SimpleApplication implements ActionListener, PhysicsCollisionListener {

  private Player p;
  private ArrayList<Character> characterArray = new ArrayList<Character>();
  private boolean isRunning;
  
  private int playerTeamID; //0 is defednding, 1 is attacking
  private int numberOfNUPs = 0;
  
  
  //displaySettings     
  private CameraView camView;
  private int camState = 0;
  private static float timePerFrame;
  int collTime = 0;
  
  
 //I/O operations
  private static boolean isLogging;
  private int logTime = 0;
  private Thread writeThread;
  static String path;

  //cultural dimensions of environment
//  private float individualism;
//  private float masculinity;
//  private float powerDistance;
//  private float uncertaintyAvoidance;
//  private float longTermOrientation;

  static boolean isImmersive = true;
 // static boolean hasFixedOrientation = false;
  
  float aspectRatio = 0.1f;
  
  //network settings
  UDPBroadcastServer broadcastServer;
  SensorClient sensorClient;
  
  private int newID = -1;
  private Vector3f newPos = null;
  private int targetsReached = 0;
  
 // public int IDCounter = 0;
  
  KinectClient kinectClient;

  private SceneCreator sceneCreator;
  private CharacterCreator characterCreator;
  private ObjectCreator objectCreator;
  private ModelLoader modelLoader;
  private SceneCharacterManager sceneCharacterManager;
  private SceneObjectManager sceneObjectManager;
  private UserNavigation userNavigation;
  private MainLogicThread agentThread;
  
  private String playerModelType = "D";
  
  private boolean startScreenCompleted = false;
  private boolean loadingState;
  private Thread loadingThread;
  
  NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay();
  private Nifty nifty;
  private StartInterface startInterface;
  private InitialSettings initialSettings = new InitialSettings();
  private String gameType;
  private int gameState = 0; // 0 = game not initialised, 1 = waiting for client entries, 2 = game is being played
  public GameStateManagement gsm;
  private Game game;
  
  public static void main(String[] args) {
        Main gameApp = new Main();   
        AppSettings settings = new AppSettings(true);
        settings.setTitle("VIRTUAL BASKETBALL");
        gameApp.setShowSettings(false);
        gameApp.setDisplayStatView(false);
        gameApp.setDisplayFps(false);
        gameApp.setSettings(settings);
        gameApp.start();
    }

  public void simpleInitApp() {
      Logger.getLogger("").setLevel(Level.WARNING);
      this.executeStartScreen();
  }
  
  public void finishLoading(InitialSettings i){
      
      initialSettings = i;
      gameType = i.getGameType();
      
      if(gameType.equals("Team")){ 
          game = new PickupGame();
      }
      else if(gameType.equals("Dribbling")){
          game = new Dribbling();
      }
      else if(gameType.equals("Passing")){
          game = new Passing();
      }
      else if(gameType.equals("Imitation")){
          game = new ImitationGame();
      }
      else{
          game = new Shooting();
      }

      game.setManagers(stateManager, assetManager, renderManager, inputManager);
      game.setNodes(rootNode, guiNode);
      game.setCameraInfo(cam, viewPort);
      game.setSettings(initialSettings); 
      
      //create loading screen thread
      loadingState = true;
      loadingThread = new Thread(game);
      loadingThread.start();
      loadingThread.setDaemon(true);
  }
  
  //used to update camera frustum before app.restart()
  Callable<Void> changeCameraCallable = new Callable<Void>() {

        public Void call(){
            game.refreshCameras(initialSettings.getFOV());
           // camView.changeImmersiveFieldOfView(initialSettings.getFOV());            
            return null;
        }
  };
  
  
    //used to update camera frustum before app.restart()
  Callable<Void> loadScreenCallable = new Callable<Void>() {

        public Void call(){
            startInterface.setClientWaitingMessage(game.getClientNumber(), game.loadTimeRemaining());      
            return null;
        }
  }; 
  
  private void changeResolution(int width, int height){ 
      settings.setResolution(width, height);
      this.setSettings(settings);
      this.restart();
  }
  
  private void cleanUpLoadingScreen(){      
      guiViewPort.removeProcessor(niftyDisplay);   
      niftyDisplay.getNifty().exit();
      
       if(initialSettings.getImmersive()){
          this.changeResolution(initialSettings.getResolution()[0] * initialSettings.getNumDisplays(), initialSettings.getResolution()[1]);
          this.enqueue(changeCameraCallable);
          Display.setLocation(-initialSettings.getResolution()[0] * initialSettings.getActivityScreen(), 0);
      }
      else{     
         this.changeResolution(initialSettings.getResolution()[0], initialSettings.getResolution()[1]);
      }
       
       startScreenCompleted = true;  
       isRunning = true;
  }
    
//  private void initializeGlobalSettings(){
//      membersPerTeam = initialSettings.getNumPlayers();
//          
//      if(!gameType.equals("Team") && !gameType.equals("Passing")){
//          numberOfTeams = 1;
//          playerTeamID = 0;
//      }
//      else{
//          numberOfTeams = 2;
//          if(initialSettings.getOffense()){
//              playerTeamID = 1;
//          }
//          else{
//              playerTeamID = 0;
//          }
//      }
//  }
  
  public int getPlayerTeamID(){
      return playerTeamID;
  }
  
  private void executeStartScreen(){
      
    niftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);
    nifty = niftyDisplay.getNifty();
    Logger.getLogger("de.lessvoid.nifty").setLevel(Level.SEVERE); 
    Logger.getLogger("NiftyInputEventHandlingLog").setLevel(Level.SEVERE); 
    startInterface = new StartInterface(this);
    nifty.fromXml("Interface/StartScreen.xml", "start", startInterface);
    guiViewPort.addProcessor(niftyDisplay);
    flyCam.setDragToRotate(true); 

  }
  
//  private void loadGame(){
//      
//    if(isLogging){
//        Log.clearFile(path);
//        Log.write(path, "*------------------------------------*");
//    }
//    
//    bulletAppState = new BulletAppState();
//    stateManager.attach(bulletAppState);
//    modelLoader  = new ModelLoader(assetManager);
//    characterCreator = new CharacterCreator(rootNode, bulletAppState);      
//    sceneCreator = new SceneCreator(rootNode, bulletAppState);
//    objectCreator = new ObjectCreator(rootNode, bulletAppState);
// //   sceneCharacterManager = new SceneCharacterManager(this, characterArray, characterCreator, rootNode, bulletAppState);
//    camView = new CameraView(cam, initialSettings.getImmersive(), initialSettings.getFixedOrientation());
//    JointProjectXMLProcessor jmp = new JointProjectXMLProcessor();
//    BehaviorXMLProcessor bp = new BehaviorXMLProcessor();
//    
//    createEnvironment();
//    createBall();
//    sceneObjectManager = new SceneObjectManager(ball);
//    createPlayer();
//    createTeamsAndAgents();
//    p.initializePlayerGesture(ball);
//    
//    agentThread = new MainLogicThread(characterArray, ball);
//    
//    isRunning = true;
//    
//    userNavigation = new UserNavigation(p, initialSettings.getFixedOrientation(), cam);
//    this.customizeEnvironment();
//    
//    gameState = 2; // now in middle of game
//  }
//  
//  private void setupNetwork(String network, String address, int port1, int port2){
//      
////      if(network.equals("Server")){
////          broadcastServer = NetworkConnections.createBroadcastServer(port2, this);
////          TCPServer = NetworkConnections.createTCPServer(port1, this, broadcastServer);
////      }
////      else if(network.equals("Kinect")){
////          kinectClient = (KinectClient)NetworkConnections.createClient(4, port1, this, address);
////      }
////      else if(network.equals("Pressure Sensor")){
////          sensorClient = (SensorClient)NetworkConnections.createClient(3, port1, this, address);
////      }
//      
//  }
//  
//  private void createEnvironment(){
//    /** Set up Physics */
//    viewPort.setBackgroundColor(new ColorRGBA(0.7f,0.8f,1f,1f));
//    if(initialSettings.getImmersive()){
//          int nod = initialSettings.getNumDisplays();
//          int dispH = initialSettings.getResolution()[1];
//          int dispW = initialSettings.getResolution()[0];
//          float fov = initialSettings.getFOV();
//          int ms = initialSettings.getMainScreen();
//          camView.setupImmersiveCameras(renderManager, rootNode, nod, dispH, dispW, fov, ms);
//    }
//    this.setupKeys();
//
//    sceneCreator.addLights(rootNode);
//    sceneCreator.loadScene("Scenes/town/main.j3o", assetManager, rootNode);
//    sceneCreator.attachObjects(rootNode);
//  }
//  
//  private void customizeEnvironment(){
//      
//      if(gameType.equals("Dribbling") || gameType.equals("Shooting")){
//          this.createPlayerTarget();
//      }
//      else if(gameType.equals("Passing")){
//          
//          float z = -4f;
//          
//          p.setPosition(new Vector3f(16, p.getPosition().y, -16));
//          p.makePlayerTransparent();
//          ArrayList<Character> players = SceneCharacterManager.getCharacterArray();
//          
//          for(Character c : players){              
//              if(c instanceof VISIE.characters.BasketballAgent){
//                  BasketballAgent ba = (BasketballAgent)c;
//                  
//                  if(ba.getTeamID() == p.getTeamID()){
//                      ba.setPosition(new Vector3f(-9, ba.getPosition().y, z));
//                      z = z - 24;
//                  }
//                  else{
//                      ba.setPosition(new Vector3f(-9, ba.getPosition().y, -16));
//                  }
//                  
//                  ba.setTrainingBehaviorModule(p.getTeamID());
//              }
//              
//              
//          }
//      }
//      
//  }
//  
// 
//
//    /** We over-write some navigational key mappings here, so we can
//   * add physics-controlled walking and jumping: */
//  private void setupKeys() {
//      
//    inputManager.addMapping("Lefts",  new KeyTrigger(KeyInput.KEY_LEFT));
//    inputManager.addMapping("Rights", new KeyTrigger(KeyInput.KEY_RIGHT));
//    inputManager.addMapping("Ups",    new KeyTrigger(KeyInput.KEY_UP));
//    inputManager.addMapping("Downs",  new KeyTrigger(KeyInput.KEY_DOWN));
//    inputManager.addMapping("Jumps",  new KeyTrigger(KeyInput.KEY_SPACE));
//    inputManager.addMapping("Pause",  new KeyTrigger(KeyInput.KEY_P));
//    inputManager.addMapping("A Type Camera", new KeyTrigger(KeyInput.KEY_A));
//    inputManager.addMapping("B Type Camera", new KeyTrigger(KeyInput.KEY_B));
//    inputManager.addMapping("Top Camera", new KeyTrigger(KeyInput.KEY_T));
//    inputManager.addMapping("Aspect Ratio", new KeyTrigger(KeyInput.KEY_O));
//    inputManager.addMapping("CamState0", new KeyTrigger(KeyInput.KEY_0));
//    inputManager.addMapping("CamState1", new KeyTrigger(KeyInput.KEY_1));
//    inputManager.addMapping("CamState2", new KeyTrigger(KeyInput.KEY_2));
//    inputManager.addMapping("Increase FOV", new KeyTrigger(KeyInput.KEY_HOME));
//    inputManager.addMapping("Decrease FOV", new KeyTrigger(KeyInput.KEY_END));
//    inputManager.addMapping("Get ball", new KeyTrigger(KeyInput.KEY_B));
//    inputManager.addListener(this, "Lefts");
//    inputManager.addListener(this, "Rights");
//    inputManager.addListener(this, "Ups");
//    inputManager.addListener(this, "Downs");
//    inputManager.addListener(this, "Jumps");
//    inputManager.addListener(this, "Pause");
//    inputManager.addListener(this, "A Type Camera");
//    inputManager.addListener(this, "B Type Camera");
//    inputManager.addListener(this, "Top Camera");
//    inputManager.addListener(this, "Aspect Ratio");
//    inputManager.addListener(this, "Transaction");
//    inputManager.addListener(this, "CamState0");
//    inputManager.addListener(this, "CamState1");
//    inputManager.addListener(this, "CamState2");
//    inputManager.addListener(this, "Increase FOV");
//    inputManager.addListener(this, "Decrease FOV");
//    inputManager.addListener(this, "Get ball");
//    
//    //player animations
//    inputManager.addMapping("Accept Pass", new KeyTrigger(KeyInput.KEY_H));
//    inputManager.addListener(this, "Accept Pass");
//    inputManager.addMapping("Shoot Ball", new KeyTrigger(KeyInput.KEY_K));
//    inputManager.addListener(this, "Shoot Ball");
//    inputManager.addMapping("Propose Pass", new KeyTrigger(KeyInput.KEY_L));
//    inputManager.addListener(this, "Propose Pass");
//    inputManager.addMapping("Pass Ball", new KeyTrigger(KeyInput.KEY_SEMICOLON));
//    inputManager.addListener(this, "Pass Ball");
//    inputManager.addMapping("Call for pass", new KeyTrigger(KeyInput.KEY_S));
//    inputManager.addListener(this, "Call for pass");
//    inputManager.addMapping("Point to goal", new KeyTrigger(KeyInput.KEY_V));
//    inputManager.addListener(this, "Point to goal");
//    
//    //ball triggers
//    inputManager.addMapping("BallTriggerShoot", new KeyTrigger(KeyInput.KEY_X));
//    inputManager.addListener(this, "BallTriggerShoot");
//    inputManager.addMapping("BallTriggerPass", new KeyTrigger(KeyInput.KEY_Z));
//    inputManager.addListener(this, "BallTriggerPass");
//  }

    /** These are our custom actions triggered by key presses.
   * We do not walk yet, we just keep track of the direction the user pressed. */
  public void onAction(String binding, boolean value, float tpf) {}
//    if (binding.equals("Lefts")) {
//        userNavigation.setDirectionKeys(value, 2);
//    } else if (binding.equals("Rights")) {
//        userNavigation.setDirectionKeys(value, 3);
//    } else if (binding.equals("Ups")) {
//        userNavigation.setDirectionKeys(value, 0);
//    } else if (binding.equals("Downs")) {
//        userNavigation.setDirectionKeys(value, 1);
//    } else if (binding.equals("Pause") && !value) {
//        pauseGame();
//    } else if (binding.equals("A Type Camera") && !value) {
//      ATypeCamera = !ATypeCamera;
//      BTypeCamera = false;
//      topCamera = false;
//    } else if (binding.equals("B Type Camera") && !value) {
//      BTypeCamera = !BTypeCamera;
//      ATypeCamera = false;
//      topCamera = false;
//    }
//     else if (binding.equals("Top Camera") && !value) {
//      BTypeCamera = false;
//      ATypeCamera = false;
//      topCamera = !topCamera;
//    }
//    else if (binding.equals("CamState0")) {
//        camState = 0;
//    }
//    else if (binding.equals("CamState1")) {
//        camState = 1;
//    }
//    else if (binding.equals("CamState2")) {
//        camState = 2;
//    }
//     else if(binding.equals("Transaction") && !value){
//         ball.removeDamping();                  
//     }
//    else if(binding.equals("Jumps") && !value){
//        p.jump();
//     }
//     else if(binding.equals("Propose Pass") && !value && p.isInPossession()){
//            p.playAnimation(1, "initiatePass", 0.5f, LoopMode.DontLoop);
//     }
//     else if(binding.equals("Shoot Ball") && !value && p.isInPossession() && p.canShoot()){
//         p.shootBall();
//     }
//     else if(binding.equals("Pass Ball") && p.isInPossession()){
//         p.playAnimation(1, "passAction", 0.5f, LoopMode.DontLoop);
//     }
//     else if(binding.equals("Call for pass") && !p.isInPossession()){
//         p.playAnimation(1, "callForPass", 0.75f, LoopMode.DontLoop);
//     }
//     else if(binding.equals("Accept Pass") && !p.isInPossession() && !value){
//         
//         if(p.getCurrentGesture(1).equals("standingPose")){
//              p.playAnimation(1, "acceptPass", 0.75f, LoopMode.DontLoop);
//         }
//         else{
//             p.playAnimation(1, "standingPose", 0.75f, LoopMode.DontLoop);
//         }
//     }
//     else if(binding.equals("Point to goal") && !value && !p.isInPossession()){
//     //    p.playDynamicAnimation("Point to goal");
//     }
//     else if(binding.equals("BallTriggerShoot") && !value && p.isInPossession()){
//         
//         if(p instanceof VISIE.characters.KinectPlayer){
//            KinectPlayer kp = (KinectPlayer)p;
//            kp.playKinectGesture("Shoot");
//         }
//     }
//     
//     else if(binding.equals("BallTriggerPass") && !value && p.isInPossession()){
//         if(p instanceof VISIE.characters.KinectPlayer){
//            KinectPlayer kp = (KinectPlayer)p;
//            kp.throwPass();
//         }
////         kp.playKinectGesture("Pass");
//     }
//    
//     else if(binding.equals("Increase FOV") && !value){
//         this.increaseCameraFOV();
//     }
//     else if(binding.equals("Decrease FOV") && !value){
//         this.decreaseCameraFOV();
//     }
//     else if(binding.equals("Get ball") && !value){
//         ball.setPossession(p.getID());
//         p.setPossession();
//     }
//    
//  }
  
//  private void increaseCameraFOV(){
//     float prev = camView.getCameraFOV();
//     camView.changeImmersiveFieldOfView(prev + 1);
//  }
//  
//  private void decreaseCameraFOV(){
//     float prev = camView.getCameraFOV();
//     camView.changeImmersiveFieldOfView(prev - 1);
//  }
//  
  
  
//   private void createPlayer(){   
//     Vector3f startPosition = CharacterCreator.generateStartingPosition(playerTeamID);
//     startPosition.setY(4);
//     String[] textures = VISIEFileReader.readPlayerConfiguration(Integer.toString(playerTeamID));
//     p = characterCreator.addPlayerCharacter(sceneCharacterManager.IDCounter, playerModelType, rootNode, startPosition, textures, kinectClient != null);
//     characterArray.add(p);
//     UserNavigation.setInitialCameraRotation((float)Math.toRadians(-90));
//     SceneCharacterManager.IDCounter++;
//     p.setBall(ball);
//     logNewPlayer(p);
//  }
//   
//   private void createBall(){
//       ball = objectCreator.createBall(new Vector3f(-5f, 10, -14f), rootNode);
//   } 
//   
//
//   private void createTeamsAndAgents(){
//       
//       for(int i = 0; i < numberOfTeams; i++){
//           
//           int agentsInTeam;
//           
//           if(i == playerTeamID){
//               agentsInTeam = membersPerTeam - numberOfNUPs - 1;
//           }
//           else{
//               if(gameType.equals("Passing")){
//                    agentsInTeam = 1;
//               }
//               else{
//                    agentsInTeam = membersPerTeam;
//               }
//           }
//           
//           if(agentsInTeam < 0){ //adjust for NUPs
//               agentsInTeam = 0;
//           }
//           
//           BasketballTeam team = new BasketballTeam(agentsInTeam, characterCreator, i);
//
//           if(team.getTeamID() == playerTeamID){
//               p.setTeam(team);
//               team.addToTeam(p);
//           }  
//
//           ArrayList<Character> c = team.initialisePlayers(i, ball);
//           for(int j = 0; j < c.size(); j++){
//               characterArray.add(c.get(j));
//           }
//           
//           teams.add(team);
//           if(team.getTeamID() == 1){
//               team.setAttacking();
//           }
//       }
//       
//       //sets possession character
//       BasketballCharacter startPossessionCharacter;
//       if(numberOfTeams > 1){
//            startPossessionCharacter = (BasketballCharacter)teams.get(1).getRandomTeamMate();
//       }
//       else{
//           startPossessionCharacter = p;
//       }
//       startPossessionCharacter.setPossession();
//       
//      if(startPossessionCharacter instanceof VISIE.characters.BasketballAgent){
//           BasketballAgent ba = (BasketballAgent)startPossessionCharacter;
//           ba.setBehaviorState(0);
//       }
//       
//      //set initial facing directions
//       for(int i = 0; i < characterArray.size(); i++){
//           BasketballCharacter bc = (BasketballCharacter)characterArray.get(i);
//           
//           if(bc instanceof VISIE.characters.BasketballAgent){
//               BasketballAgent ba = (BasketballAgent)bc;
//               float initRot;
//               
//               if(startPossessionCharacter.getTeamID() == ba.getTeamID()){ 
//                   initRot = Conversions.originToTargetAngle(ba.getPosition(), Court.getHoopLocation());
//               }
//               else{
//                   initRot = Conversions.originToTargetAngle(ba.getPosition(), SceneCharacterManager.getCharacterInPossession().getPosition());
//               }
//               ba.abo.setFacingDirection(initRot, initRot);
//           }
//           
//       }
//
////        bulletAppState.getPhysicsSpace().enableDebug(assetManager);   
//   }
//
//    
//
//
//   private void createWriteThread(){
//   Log.clearFile("test.txt");
//
//   Runnable r1 = new Runnable(){
//        public void run(){
//            try{
//                while(true){
//                    if(isRunning){
//                        writeToFile();
//                        Thread.sleep(10000);
//                    }
//                }
//
//            }
//            catch(InterruptedException e){}
//        }
//    };
//    
//    writeThread = new Thread(r1);
//    writeThread.setDaemon(true);
//    writeThread.start();
//   }
// 
//
// private void playerMovement(float tpf){
//    
//    cameraRot = userNavigation.executeNavigation(isRunning, tpf, sensorClient);
//    
//    if(ATypeCamera)
//        showViewPoint(1);
//    else if(BTypeCamera)
//        showViewPoint(2);
//    else if(topCamera)
//        this.topCamera();
//    else
//        showViewPoint(0); 
//  //  System.out.println(p.getPosition());
//   }
//
//   private void showViewPoint(int characterID){
//       
//       float f = p.getFacingDirection();
//       
//       if(p instanceof KinectPlayer){
//           KinectPlayer kp = (KinectPlayer)p;
//           f = kp.getCameraDirection();
//       }
//       
//       if(!initialSettings.getImmersive()){
//            camView.showViewPoint(p.getPosition(), (float)Math.toDegrees(cameraRot), camState);
//       }
//       else{
//            camView.showImmersiveViewPoint(p.getHeadPosition(), f, camState);
//       }
//   }
//
//   private void topCamera(){
//       cam.setLocation(new Vector3f(0, 100f, -10));
//       cam.setRotation(new Quaternion().fromAngles((float)Math.toRadians(90), 0, 0));
//   }

   public void collision(PhysicsCollisionEvent event){
       
   }
   
  @Override
  public void simpleUpdate(float tpf) {
      
     if(loadingState){
         
       if(initialSettings.getMultiPlayer()){  
           ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(2);
           exec.submit(loadScreenCallable);        
           exec.shutdown();
       }
         
        if(game != null && game.isLoadingComplete()){
              game.loadGame();
              this.cleanUpLoadingScreen();
              loadingState = false;
        }
      }
      
      if(startScreenCompleted){    
        //createLoading();
              if(isRunning){                                  
                timePerFrame = tpf;
                game.updateGame(tpf);
          }
      }
  }

  
//  public void doTrainingBehavior(){
//       if(gameType.equals("Dribbling")&& p.hasReachedTarget()){ 
//          targetsReached++;
//          this.createPlayerTarget();
//          System.out.println(targetsReached);
//      }
//      else if(gameType.equals("Shooting")){
//         if(p.hasReachedTarget()){   
//              SceneCreator.changeTargetColour("playerTarget", true);                    
//              if(p.getCurrentGesture().equals("Shoot")){
//                  targetsReached++;
//                  this.createPlayerTarget();
//                  System.out.println(targetsReached);
//              }          
//         }
//         else{
//             SceneCreator.changeTargetColour("playerTarget", false);
//         }
//      }
//  
//  }
//  
//  private void createPlayerTarget(){
//      
//      Vector3f targetPos = new Vector3f();
//      
//      if(rootNode.getChild("playerTarget") != null){
//          rootNode.getChild("playerTarget").removeFromParent();
//      }   
//      if(gameType.equals("Dribbling")){
//        targetPos = Conversions.generateRandomPosition(p.getPosition(), 20f, 40f);
//      }
//      else if(gameType.equals("Shooting")){
//        targetPos = Conversions.generateRandomPosition(Court.getGoalPosition(), 15f, 25f);
//      }
//      SceneCreator.addTargetNode(targetPos);
//      p.setPlayerTarget(targetPos);
//  
//  }
//    
//  private void updateTeamInformation(){
//      
//      if(SceneCharacterManager.getCharacterByID(ball.getLastTouched()) != null){
//            Character c = SceneCharacterManager.getCharacterByID(ball.getLastTouched());
//            for(int i = 0; i < teams.size(); i++){
//                if(teams.get(i).isMember(c)){
//                    teams.get(i).setAttacking();
//                }
//                else{
//                    teams.get(i).setDefending();
//                }
//            }
//      }
//  }
//  
////  public boolean isBallOut(){
////      Character c = SceneCharacterManager.getCharacterInPossession();
////      
////      if(c != null){
////          return !Court.isInsideCourt(c.getPosition());
////      }
////      else{
////          return !Court.isInsideCourt(ball.getBallPosition());
////      }
////  }
  
  public static float getFrameRate(){
     // System.out.println
      return Math.min(timePerFrame, 0.05f);
  }
  
//  private void updatePlayerSkeleton(){
//      
//      KinectPlayer kp = (KinectPlayer)p;
//      NetworkMessagingProcessor.parseKinectJointMessage(kp);  
//      
//      if(kinectClient.getCurrentGesture().equals("shoot") && p.canShoot() && !kp.isDribbling()){
// //         System.out.println("shoot " + (p.getHandPosition(1).y - p.getShoulderPosition(1).y));
//          kp.playKinectGesture("Shoot");
//      }
//      else if(kinectClient.getCurrentGesture().equals("dribbleRight") && p.isInPossession()){
//          kp.playKinectGesture("Dribble Right");
//      }
//      else if(kinectClient.getCurrentGesture().equals("pass") && !kp.isDribbling()){
//          
//          //check for false positive pass
//          if(!initialSettings.getGameType().equals("Passing") &&
//              p.getHandPosition(1).y - p.getElbowPosition(1).y > 1f){
//              System.out.println("false positive");
//     //        kp.playKinectGesture("Shoot");
//              kp.playKinectGesture("");
//          }
//          else{
//            kp.playKinectGesture("Pass");
//          }
//      }
//      else if(kp.isDribbling()){
//  //        kp.playKinectGesture("dribbleRight");
//      }
//      else{
//          kp.playKinectGesture("");
//      }
//  }
  
  public void pauseGame(){
      isRunning = !isRunning;
//      if(isRunning)
//          bulletAppState.setSpeed(1.0f);
//      else
//          bulletAppState.setSpeed(0);
  }


//  private void writeToFile(){
//      ArrayList<Character> players = SceneCharacterManager.getCharacterArray();
//      StringBuilder s = new StringBuilder();
//      
//      s.append(logTime + "$");
//      s.append("B" + ball.getBallPosition() + "$");
//      
//      for(int i = 0; i < players.size(); i++){
//          Character c = players.get(i);
//          
//          if(c instanceof VISIE.characters.Player){
//              s.append(c.getID() + "P$");
//              s.append(c.getPosition() + "$");
//              s.append(c.getFacingDirection() + "$");
//              if(c instanceof VISIE.characters.KinectPlayer){
//                    s.append(c.getSkeletonRotations() + "$");
//              }
//              else{
//                    s.append(c.getActionState() + "$");       
//              }
//              s.append(c.getWalkingState() + "$");
//          }
//          else if(c instanceof VISIE.characters.BasketballAgent){
//              s.append(c.getID() + "A$");
//              s.append(c.getPosition() + "$");
//              s.append(c.getFacingDirection() + "$");
//              s.append(c.getActionState() + "$");
//              s.append(c.getWalkingState()  + "$");
//          }
//          else if(c instanceof VISIE.characters.NonUserPlayer){
//              s.append(c.getID() + "N$");
//              s.append(c.getPosition() + "$");
//              s.append(c.getFacingDirection() + "$");
//              
//              NonUserPlayer nup = (NonUserPlayer)c;
//              
//              if(nup.getKinectNUP()){
//                    s.append(c.getSkeletonRotations() + "$");
//              }
//              else{
//                    s.append(c.getActionState() + "$");       
//              }
//              s.append(c.getWalkingState() + "$");
//          }
//      }
//      
//      Log.write(path, s.toString());
//      
//      logTime++;
//      
//  }
  
  public Vector3f getPlayerPos(){
      return p.getPosition(); 
  }
  
  public ArrayList<Character> getCharacterPositions(){
      return characterArray;
  }

    
//  public Geometry createTargetPointer(){
//        Sphere s = new Sphere(10, 10, 0.1f);
//        Geometry targetGeo = new Geometry("target", s);
//        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
//        mat.setColor("Color", ColorRGBA.Red);
//        targetGeo.setMaterial(mat);
//        return targetGeo;
//  }
//  
//  public int getGameState(){
//      return gameState;
//  }  
  
//  public void setNUPToTeam(NonUserPlayer nup){
//      BasketballTeam bt = null;
//      
//      for(int i = 0; i < teams.size(); i++){
//          if(p.getTeamID() == teams.get(i).getTeamID()){
//              bt = (BasketballTeam)teams.get(i);
//              break;
//          }
//      }  
//      nup.setTeam(bt);
//      bt.addToTeam(nup);
//      broadcastServer.setMessage("TEAM" + bt.getTeamID() + "," + nup.getID());
//  }
  
  //checks if number of non user players are added in the array
  private boolean areClientsAdded(){
      return numberOfNUPs == SceneCharacterManager.getNumberOfNUPS();
  }
  
  public void refresh(){
      sceneCharacterManager.updateSceneObjects();
  }
  

//  public void removeNUP(){
//      numberOfNUPs--;
//  }
//  
//  public void addNUP(){
//      numberOfNUPs++;
//  }
  
//  public void setJumpingPlayer(){
//      p.jump();
//  }
//  
//  public static void logNewPlayer(BasketballCharacter ba){
//      if(isLogging){
//         
//          String characterType = "A";
//          
//          if(ba instanceof VISIE.characters.Player){
//              characterType = "P";
//          }         
//          else if(ba instanceof VISIE.characters.NonUserPlayer){
//              characterType = "N";
//          }
//          
//          StringBuilder s = new StringBuilder();             
//          s.append("NEW" + ba.getModelType() + "!" + characterType + "!" + ba.getID() + "!");
//          
//          for(int i = 0; i < ba.getModelTextures().size(); i++){
//              s.append(ba.getModelTextures().get(i));
//          }        
//          s.append(ba.getPosition());
//          Log.write(path, s.toString());
//      }
//  }
  
  
}

